package com.flyox.game.militarychess.server.business;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Date;

import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;

import org.apache.mina.common.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.flyox.game.militarychess.CONSTS;
import com.flyox.game.militarychess.bean.Player;
import com.flyox.game.militarychess.message.ChessPackage;
import com.flyox.game.militarychess.message.Response;
import com.flyox.game.militarychess.server.services.PlayerService;
import com.flyox.game.militarychess.util.SerialUtil;

public class HelloService {
	private final Logger logger = LoggerFactory.getLogger(getClass());
	PlayerService playerService=new PlayerService();
	/**
	 * 第一次建立连接
	 * @param session
	 */
	public void processHello(IoSession session) {
		logger.info("one login in");
		Response response = new Response();
		response.setResponseType(CONSTS.CMD_HELLO);
		response.setRes(CONSTS.RESPONSE_OK);
		// 返回一个 唯一号
		String pID = Player.genPlayerID();
		response.setId(pID);
		Player player = new Player(pID);
		player.setStates(CONSTS.PLAYER_STATS_HELLO);
		player.setLoginTime(new Date());
		playerService.addPlayer(player);
		//send res
		try {
			ChessPackage cp=new ChessPackage(CONSTS.CMD_HELLO,pID);
			cp.setContent(SerialUtil.enSerial(response));
			session.write(cp);
			session.setAttribute(CONSTS.SYS_SESSION_PLAYERID,pID);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 根据唯一号 服务端生成公钥
	 * @param session
	 * @param playerID
	 */
	public void processHand1(IoSession session,String playerID) {
		Response response = new Response();
		if(playerID==null||playerID.length()!=40){
			response.setRes(CONSTS.RESPONSE_ERROR);
		}else if (!playerService.getPlayers().containsKey(playerID)) {
			response.setRes(CONSTS.RESPONSE_ERROR);
		}else if(playerService.getPlayerState(playerID)!=CONSTS.PLAYER_STATS_HELLO){
			response.setRes(CONSTS.RESPONSE_ERROR);
		}else {
			try {
				Player player = playerService.getPlayer(playerID);
				player.setStates(CONSTS.PLAYER_STATS_HAND1);
				KeyPairGenerator keyPair = KeyPairGenerator.getInstance("DH");
				keyPair.initialize(1024);
				KeyPair serverKeyPair = keyPair.generateKeyPair(); // 生成时间长
				player.setKeyPair(serverKeyPair);
				
				//
				byte[] serverPubKeyEnc = serverKeyPair.getPublic().getEncoded();
				response.setPubKeyEnc(serverPubKeyEnc);
				response.setRes(CONSTS.RESPONSE_OK);
			} catch (NoSuchAlgorithmException e) {
				response.setRes(CONSTS.RESPONSE_ERROR);
				e.printStackTrace();
				logger.error(e.getMessage());
			}
		}
		//send res
		try {
			ChessPackage cp=new ChessPackage(CONSTS.CMD_HAND_1,playerID);
			cp.setContent(SerialUtil.enSerial(response));
			session.write(cp);
		} catch (IOException e) {
			e.printStackTrace();
			logger.error(e.getMessage());
		}
	}
	
	public void processHand2(IoSession session,String playerID,byte[] pk) {
		Response response = new Response();
		if(playerID==null||playerID.length()!=40){
			response.setRes(CONSTS.RESPONSE_ERROR);
		}else if (!playerService.getPlayers().containsKey(playerID)) {
			response.setRes(CONSTS.RESPONSE_ERROR);
		}else if(playerService.getPlayerState(playerID)!=CONSTS.PLAYER_STATS_HAND1){
			response.setRes(CONSTS.RESPONSE_ERROR);
		} else {
			try {
				Player player = playerService.getPlayer(playerID);
				
				KeyFactory serverKeyFac = KeyFactory.getInstance("DH");
				X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pk);
				// 还原客户端公钥
				PublicKey clientPubKey = serverKeyFac.generatePublic(x509KeySpec);
				KeyAgreement serverKeyAgree = KeyAgreement.getInstance("DH");
				serverKeyAgree.init(player.getKeyPair().getPrivate());
				serverKeyAgree.doPhase(clientPubKey, true);
				// 生成本地的密钥
				SecretKey desKey = serverKeyAgree.generateSecret("DES");
				player.setDesKey(desKey);
				player.setStates(CONSTS.PLAYER_STATS_HAND2);
				
				//
				response.setRes(CONSTS.RESPONSE_OK);
			} catch (InvalidKeyException e) {
				response.setRes(CONSTS.RESPONSE_ERROR);
				e.printStackTrace();
			} catch (NoSuchAlgorithmException e) {
				response.setRes(CONSTS.RESPONSE_ERROR);
				e.printStackTrace();
			} catch (InvalidKeySpecException e) {
				response.setRes(CONSTS.RESPONSE_ERROR);
				e.printStackTrace();
			}
		}
		//send res
		try {
			ChessPackage cp=new ChessPackage(CONSTS.CMD_HAND_2,playerID);
			cp.setContent(SerialUtil.enSerial(response));
			session.write(cp);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
